//关于这个项目的笔记先记到这个文件里
//编写一个数据类型来表示单位正方形中的一组点（所有点的x和y坐标都在 0 和 1 之间）
//使用2d 树来支持高效范围搜索（查找查询矩形中包含的所有点）和最近邻搜索（查找查询点的最近点）。
//2d 树具有广泛的应用，从对天文物体进行分类到计算机动画，再到加速神经网络、挖掘数据和图像检索。

import edu.princeton.cs.algs4.Point2D;
import edu.princeton.cs.algs4.RectHV;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.SET;

//写下思路
//首先要查看红黑树的api
//就单用红黑树表示点就可以，这里key用Point2D就可以，至于值就设置递增i就得了。
//在这里是构建红黑树暴力查找

public class PointSET {
    private SET<Point2D> pointSet;
    //构造一个空点集,
    public PointSET() // construct an empty set of points
    {
      //这里构建的是点的集合
      pointSet=new SET<Point2D>();
    }

    //集合是否为空？
    public boolean isEmpty() // is the set empty?
    {
        return pointSet.isEmpty();
    }

    //集合中的点数
   public               int size()                         // number of points in the set 
   {
       return pointSet.size();
   }

   //将点添加到集合（如果集合中尚不存在该点）
   public              void insert(Point2D p)              // add the point to the set (if it is not already in the set)
   {
        pointSet.add(p);
   }

   //集合是否包含点 p？
   public           boolean contains(Point2D p)            // does the set contain point p? 
   {
       return pointSet.contains(p);
   }

   //将所有点绘制为标准绘制
   public              void draw()                         // draw all points to standard draw 
   {
       for(Point2D point:pointSet)
       {
         point.draw();
       }
   }

   //矩形内（或边界上）的所有点 
   public Iterable<Point2D> range(RectHV rect)             // all points that are inside the rectangle (or on the boundary) 
   {
       SET<Point2D> pointInRec=new SET<Point2D>();
       for(Point2D points:pointSet)
       {
        if(rect.contains(points))
        {
            pointInRec.add(points);
        }
       }
       return pointInRec;
   }

   //集合中与点 p 最近的邻居；如果集合为空，则返回 null 
   public           Point2D nearest(Point2D p)             // a nearest neighbor in the set to point p; null if the set is empty 
   {
      Point2D min=pointSet.min();
      for(Point2D points:pointSet)
      {
        if(min.distanceTo(p)>points.distanceTo(p))
        {
            min=points;
        }
      }
      return min;
   }


   //测试
   public static void main(String[] args) // unit testing of the methods (optional)
    {
        //这里构建的是两个用来测试问题的，一个是用来查找包含点的矩形，一个是用来最近邻搜索的点
      RectHV rectTest = new RectHV(0.25, 0.25, 0.75, 0.75);
      Point2D pTest = new Point2D(0.5, 0.5);

     RectHV rect = new RectHV(0.0, 0.0, 1.0, 1.0);
     rect.draw();
        StdDraw.enableDoubleBuffering();
        PointSET PointSET = new PointSET();
        while (true) {
            if (StdDraw.isMousePressed()) {
                double x = StdDraw.mouseX();
                double y = StdDraw.mouseY();
                StdOut.printf("%8.6f %8.6f\n", x, y);
                Point2D p = new Point2D(x, y);
                if (rect.contains(p)) {
                    StdOut.printf("%8.6f %8.6f\n", x, y);
                    PointSET.insert(p);
                    // StdDraw.clear();
                    StdDraw.setPenColor(StdDraw.MAGENTA);
                    PointSET.draw();
                    StdDraw.setPenColor(StdDraw.BLUE);
                    for(Point2D point:PointSET.range(rectTest))
                    {
                        point.draw();
                    }
                    Point2D min=PointSET.nearest(pTest);
                     StdDraw.circle(min.x(), min.y(), 0.1);
                    StdDraw.show();
                }
            }
            StdDraw.pause(20);
        }

    }
}

